package com.erp.action;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletRequest;

import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.erp.dto.Apply;
import com.erp.dto.Examine;
import com.erp.dto.ProcessDeployment;
import com.erp.dto.User;

/**
 * 
 * @author 陈凯
 * 
 */
@Controller(value = "workflowAction")
@Scope(value = "prototype")
public class WorkflowAction extends ModelDrivenBaseAction<ProcessDeployment> {

	private static final long serialVersionUID = 1L;

	/**
	 * 列出已部署的流程定义
	 */
	public String listProcDef() throws Exception {
		// TODO 不操作Activiti接口，即用procDepService替代workflowService
		List<ProcessDeployment> procDefList = procDepService.listProcDef();
		request.put("procDefList", procDefList);
		return "listProcDef";
	}

	/**
	 * 列出待审批的项目
	 */
	public String listTask() throws Exception {
		User user = (User) session.get("user");
		// 获取用户代办任务的申请ID集和
		List<Map<String, Object>> variableList = workflowService
				.listTaskVariables(user.getName());
		List<Integer> idList = null;
		List<Apply> applyList = null;
		if (variableList != null) {
			idList = new ArrayList<Integer>();
			for (Map<String, Object> variable : variableList) {
				Integer formId = (Integer) variable.get("applyId");
				idList.add(formId);
			}
			// 根据申请ID集和获取申请信息
			applyList = applyService.listApplyByIdList(idList);
		}
		request.put("applyList", applyList);
		return "listTask";
	}

	/**
	 * 已办历史
	 * 
	 * @return
	 * @throws Exception
	 */
	public String listHistory() throws Exception {
		User user = (User) session.get("user");
		List<Apply> applyList = applyService.listHistoricApplyByUser(user);
		List<Examine> examineList = examineService.listExamineByUser(user);
		// 为前端处理信息
		List<Map<String, Object>> e2aList = new ArrayList<Map<String, Object>>();
		Map<String, Object> e2a;
		Examine examine;
		Apply apply;
		// 申请+审批记录
		for (int i = 0; i < examineList.size(); i++) {
			e2a = new HashMap<String, Object>();
			examine = examineList.get(i);
			apply = examine.getApply();

			e2a.put("examine", examine);
			e2a.put("apply", apply);

			e2aList.add(e2a);
		}
		request.put("e2aList", e2aList);
		request.put("applyList", applyList);
		return "listHistory";
	}

	/**
	 * 删除流程定义
	 */
	public void delete() throws Exception {
		workflowService.deleteDeploymentCascadeByKey(model.getKey());
		procDepService.deleteByKey(model.getKey());
		writeJson("msg", "true");
	}

	/**
	 * 进入流程定义部署/上传页面
	 */
	public String deployProcDefPage() throws Exception {
		return "deployProcDef";
	}

	/**
	 * 部署流程定义
	 */
	public String deployProcDef() throws Exception {
		HttpServletRequest req = getRealReq();
		FileItemStream fileStream = null;
		boolean isAjaxUpload = req.getHeader("X_Requested_With") != null;
		ServletFileUpload upload = new ServletFileUpload(
				new DiskFileItemFactory());
		if (isAjaxUpload) {
			upload.setHeaderEncoding("UTF-8");
		}
		FileItemIterator iterator = upload.getItemIterator(req);
		while (iterator.hasNext()) {
			fileStream = iterator.next();
			if (!fileStream.isFormField())
				break;
			fileStream = null;
		}

		InputStream is = fileStream.openStream();
		ZipInputStream zis = new ZipInputStream(is);
		ProcessDefinition procDef = workflowService.deployProcDef(zis);
		// 将流程定义的部署信息同步到t_proc_dep表
		procDepService.add(procDef, (User) session.get("user"));
		return "toListProcDef";
	}

	/**
	 * 挂起流程定义
	 * 
	 * @throws Exception
	 */
	public String suspendProcDef() throws Exception {
		workflowService.suspendProcDefByKey(model.getKey());
		procDepService.suspendProcDepByKey(model.getKey());
		return "toListProcDef";
	}

	/**
	 * 激活流程定义
	 * 
	 * @throws Exception
	 */
	public String activateProcDef() throws Exception {
		workflowService.activateProcDefByKey(model.getKey());
		procDepService.activateProcDepByKey(model.getKey());
		return "toListProcDef";
	}

	/**
	 * 查看流程图
	 */
	public String showProcDefImage() throws Exception {
		String procDefId = model.getProcDefId();
		String rootPath = ServletActionContext.getServletContext().getRealPath(
				"/");
		String imagPath = "images" + File.separator + "pd_img" + File.separator;
		String imagName = procDefId.replaceAll(":", "_") + ".png";
		String url = workflowService.downloadProcessDefinitionImageTo(
				procDefId, rootPath + imagPath + imagName);
		request.put("imagUrl", url);
		return "showProcDefImage";
	}

	/**
	 * 跟踪流程节点
	 */
	public String showProcInstImage() throws Exception {
		String procInstId = model.getProcInstId();
		String procDefId = workflowService.getProcDefIdByProcInstId(procInstId);
		InputStream is = workflowService.getProcInstImage(
				procDefId, procInstId);

		String rootPath = ServletActionContext.getServletContext().getRealPath(
				"/");
		String imagPath = "images" + File.separator + "pi_img" + File.separator;
		String imagName = procInstId + ".png";
		OutputStream os = null;
		try {
			File imgDir = new File(rootPath + imagPath + imagName);
			os = new FileOutputStream(imgDir);
			int count = 0;
			while ((count = is.read()) != -1) {
				os.write(count);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		request.put("imagUrl", imagPath + imagName);
		return "showProcInstImage";
	}

	/**
	 * 输出跟踪流程信息
	 * 
	 * @param processInstanceId
	 * @throws Exception
	 */
	public void traceProcess() throws Exception {
		List<Map<String, Object>> activityInfos = workflowService
				.traceProcess(model.getProcInstId());
		super.writeJson(activityInfos);
	}

}
